<!DOCTYPE html><html class=split lang=en-US-x-hixie><script src=../link-fixup.js defer=""></script>
<!-- Mirrored from html.spec.whatwg.org/multipage/web-messaging.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 10 Sep 2025 08:35:54 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<meta charset=utf-8><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name=viewport><title>HTML Standard</title><meta content=#3c790a name=theme-color><meta content="light dark" name=color-scheme><link rel=stylesheet href=../../resources.whatwg.org/standard-shared-with-dev.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/standard.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/spec.css crossorigin=""><link rel=icon href=https://resources.whatwg.org/logo.svg crossorigin=""><link rel=stylesheet href=../styles.css crossorigin=""><script>
   function toggleStatus(div) {
     div.parentNode.classList.toggle('wrapped');
   }
   function setLinkFragment(link) {
     link.hash = location.hash;
   }
  </script><body>
  
  <script defer="" crossorigin="" src=../html-dfn.js></script>
  
  <header id=head class="head with-buttons">
   <a href=https://whatwg.org/ class=logo><img width=100 alt=WHATWG crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/logo.svg height=100></a>
   <hgroup><h1 class=allcaps>HTML</h1><p id=living-standard>Living Standard — Last Updated <span class=pubdate>10 September 2025</span></hgroup>
   
   

   
  </header>

  

  

  

  
  

  
  

  

  <nav><a href=server-sent-events.html>← 9.2 Server-sent events</a> — <a href=index.html>Table of Contents</a> — <a href=workers.html>10 Web workers →</a></nav><ol class=toc><li id=toc-comms><ol><li><a href=web-messaging.html#web-messaging><span class=secno>9.3</span> Cross-document messaging</a><ol><li><a href=web-messaging.html#introduction-12><span class=secno>9.3.1</span> Introduction</a><li><a href=web-messaging.html#security-postmsg><span class=secno>9.3.2</span> Security</a><ol><li><a href=web-messaging.html#authors><span class=secno>9.3.2.1</span> Authors</a><li><a href=web-messaging.html#user-agents><span class=secno>9.3.2.2</span> User agents</a></ol><li><a href=web-messaging.html#posting-messages><span class=secno>9.3.3</span> Posting messages</a></ol><li><a href=web-messaging.html#channel-messaging><span class=secno>9.4</span> Channel messaging</a><ol><li><a href=web-messaging.html#introduction-13><span class=secno>9.4.1</span> Introduction</a><ol><li><a href=web-messaging.html#examples-5><span class=secno>9.4.1.1</span> Examples</a><li><a href=web-messaging.html#ports-as-the-basis-of-an-object-capability-model-on-the-web><span class=secno>9.4.1.2</span> Ports as the basis of an object-capability model on the web</a><li><a href=web-messaging.html#ports-as-the-basis-of-abstracting-out-service-implementations><span class=secno>9.4.1.3</span> Ports as the basis of abstracting out service implementations</a></ol><li><a href=web-messaging.html#message-channels><span class=secno>9.4.2</span> Message channels</a><li><a href=web-messaging.html#the-messageeventtarget-mixin><span class=secno>9.4.3</span> The
  <code>MessageEventTarget</code> mixin</a><li><a href=web-messaging.html#message-ports><span class=secno>9.4.4</span> Message ports</a><li><a href=web-messaging.html#ports-and-garbage-collection><span class=secno>9.4.5</span> Ports and garbage collection</a></ol><li><a href=web-messaging.html#broadcasting-to-other-browsing-contexts><span class=secno>9.5</span> Broadcasting to other browsing contexts</a></ol></ol><h3 id=web-messaging><span class=secno>9.3</span> <dfn id=crossDocumentMessages>Cross-document messaging</dfn><a href=#web-messaging class=self-link></a></h3><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage title="The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.">Window/postMessage</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>9.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>≤37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>10.1+</span></span></div></div></div>

  <p>Web browsers, for security and privacy reasons, prevent documents in different domains from
  affecting each other; that is, cross-site scripting is disallowed.</p>

  <p>While this is an important security feature, it prevents pages from different domains from
  communicating even when those pages are not hostile. This section introduces a messaging system
  that allows documents to communicate with each other regardless of their source domain, in a way
  designed to not enable cross-site scripting attacks.</p>

  <p id=fingerprint-postMessage class=note><a href=#fingerprint-postMessage class=self-link></a>
  <a id=web-messaging:tracking-vector title="There is a tracking vector here." href=https://infra.spec.whatwg.org/#tracking-vector class=tracking-vector data-x-internal=tracking-vector><img width=46 alt="(This is a tracking vector.)" crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/tracking-vector.svg height=64></a>
  The <code id=web-messaging:dom-window-postmessage><a href=#dom-window-postmessage>postMessage()</a></code> API can be used as a <a id=web-messaging:tracking-vector-2 href=https://infra.spec.whatwg.org/#tracking-vector data-x-internal=tracking-vector>tracking
  vector</a>.</p>


  <h4 id=introduction-12><span class=secno>9.3.1</span> Introduction<a href=#introduction-12 class=self-link></a></h4>

  <p><i>This section is non-normative.</i></p>

  <div class=example>

   <p>For example, if document A contains an <code id=introduction-12:the-iframe-element><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> element that contains document B,
   and script in document A calls <code id=introduction-12:dom-window-postmessage><a href=#dom-window-postmessage>postMessage()</a></code> on the
   <code id=introduction-12:window><a href=nav-history-apis.html#window>Window</a></code> object of document B, then a message event will be fired on that object,
   marked as originating from the <code id=introduction-12:window-2><a href=nav-history-apis.html#window>Window</a></code> of document A. The script in document A might
   look like:</p>

   <pre><code class='js'><c- a>var</c-> o <c- o>=</c-> document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;iframe&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
o<c- p>.</c->contentWindow<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;Hello world&apos;</c-><c- p>,</c-> <c- t>&apos;https://b.example.org/&apos;</c-><c- p>);</c-></code></pre>

   <p>To register an event handler for incoming events, the script would use <code>addEventListener()</code> (or similar mechanisms). For example, the script in document B
   might look like:</p>

   <pre><code class='js'>window<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> receiver<c- p>,</c-> <c- kc>false</c-><c- p>);</c->
<c- a>function</c-> receiver<c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c->e<c- p>.</c->origin <c- o>==</c-> <c- t>&apos;https://example.com&apos;</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c->e<c- p>.</c->data <c- o>==</c-> <c- t>&apos;Hello world&apos;</c-><c- p>)</c-> <c- p>{</c->
      e<c- p>.</c->source<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;Hello&apos;</c-><c- p>,</c-> e<c- p>.</c->origin<c- p>);</c->
    <c- p>}</c-> <c- k>else</c-> <c- p>{</c->
      alert<c- p>(</c->e<c- p>.</c->data<c- p>);</c->
    <c- p>}</c->
  <c- p>}</c->
<c- p>}</c-></code></pre>

   <p>This script first checks the domain is the expected domain, and then looks at the message,
   which it either displays to the user, or responds to by sending a message back to the document
   which sent the message in the first place.</p>

  </div>


  <h4 id=security-postmsg><span class=secno>9.3.2</span> Security<a href=#security-postmsg class=self-link></a></h4>

  

  <h5 id=authors><span class=secno>9.3.2.1</span> Authors<a href=#authors class=self-link></a></h5>

  

  <p id=security-4 class=warning>Use of this API requires extra care to protect users from
  hostile entities abusing a site for their own purposes.</p>

  <p>Authors should check the <code id=authors:dom-messageevent-origin><a href=comms.html#dom-messageevent-origin>origin</a></code> attribute to
  ensure that messages are only accepted from domains that they expect to receive messages from.
  Otherwise, bugs in the author's message handling code could be exploited by hostile sites.</p>

  <p>Furthermore, even after checking the <code id=authors:dom-messageevent-origin-2><a href=comms.html#dom-messageevent-origin>origin</a></code>
  attribute, authors should also check that the data in question is of the expected format.
  Otherwise, if the source of the event has been attacked using a cross-site scripting flaw, further
  unchecked processing of information sent using the <code id=authors:dom-window-postmessage><a href=#dom-window-postmessage>postMessage()</a></code> method could result in the attack being
  propagated into the receiver.</p>

  <p>Authors should not use the wildcard keyword (*) in the <var>targetOrigin</var>
  argument in messages that contain any confidential information, as otherwise there is no way to
  guarantee that the message is only delivered to the recipient to which it was intended.</p>

  <hr>

  <p>Authors who accept messages from any origin are encouraged to consider the risks of a
  denial-of-service attack. An attacker could send a high volume of messages; if the receiving page
  performs expensive computation or causes network traffic to be sent for each such message, the
  attacker's message could be multiplied into a denial-of-service attack. Authors are encouraged to
  employ rate limiting (only accepting a certain number of messages per minute) to make such attacks
  impractical.</p>


  

  <h5 id=user-agents><span class=secno>9.3.2.2</span> User agents<a href=#user-agents class=self-link></a></h5>

  <p>The integrity of this API is based on the inability for scripts of one <a id=user-agents:concept-origin href=browsers.html#concept-origin>origin</a> to
  post arbitrary events (using <code>dispatchEvent()</code> or otherwise) to objects in
  other origins (those that are not the <a href=browsers.html#same-origin id=user-agents:same-origin>same</a>).</p>

  <p class=note>Implementers are urged to take extra care in the implementation of this feature.
  It allows authors to transmit information from one domain to another domain, which is normally
  disallowed for security reasons. It also requires that UAs be careful to allow access to certain
  properties but not others.</p>

  <hr>

  <p>User agents are also encouraged to consider rate-limiting message traffic between different
  <a href=browsers.html#concept-origin id=user-agents:concept-origin-2>origins</a>, to protect naïve sites from denial-of-service
  attacks.</p>

  



  <h4 id=posting-messages><span class=secno>9.3.3</span> Posting messages<a href=#posting-messages class=self-link></a></h4>

  <dl class=domintro><dt><code><var>window</var>.<a href=#dom-window-postmessage-options id=dom-window-postmessage-options-dev>postMessage</a>(<var>message</var> [, <var>options</var> ])</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage title="The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.">Window/postMessage</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>9.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>10.1+</span></span></div></div></div><dd>
    <p>Posts a message to the given window. Messages can be structured objects, e.g. nested objects
    and arrays, can contain JavaScript values (strings, numbers, <code id=posting-messages:date><a data-x-internal=date href=https://tc39.es/ecma262/#sec-date-objects>Date</a></code> objects, etc.),
    and can contain certain data objects such as <code id=posting-messages:file><a data-x-internal=file href=https://w3c.github.io/FileAPI/#dfn-file>File</a></code> <code id=posting-messages:blob><a data-x-internal=blob href=https://w3c.github.io/FileAPI/#dfn-Blob>Blob</a></code>,
    <code id=posting-messages:filelist><a data-x-internal=filelist href=https://w3c.github.io/FileAPI/#filelist-section>FileList</a></code>, and <code id=posting-messages:idl-arraybuffer><a data-x-internal=idl-arraybuffer href=https://webidl.spec.whatwg.org/#idl-ArrayBuffer>ArrayBuffer</a></code> objects.</p>

    <p>Objects listed in the <code id=posting-messages:dom-structuredserializeoptions-transfer><a href=#dom-structuredserializeoptions-transfer>transfer</a></code> member
    of <var>options</var> are transferred, not just cloned, meaning that they are no longer usable
    on the sending side.</p>

    <p>A target origin can be specified using the <code id=posting-messages:dom-windowpostmessageoptions-targetorigin><a href=nav-history-apis.html#dom-windowpostmessageoptions-targetorigin>targetOrigin</a></code> member of
    <var>options</var>. If not provided, it defaults to "<code>/</code>". This default
    restricts the message to same-origin targets only.</p>

    <p>If the origin of the target window doesn't match the given target origin, the message is
    discarded, to avoid information leakage. To send the message to the target regardless of origin,
    set the target origin to "<code>*</code>".</p>

    <p>Throws a <a id=posting-messages:datacloneerror href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=posting-messages:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if
    <var>transfer</var> array contains duplicate objects or if <var>message</var> could not be
    cloned.</p>
   <dt><code><var>window</var>.<a href=#dom-window-postmessage id=posting-messages:dom-window-postmessage>postMessage</a>(<var>message</var>, <var>targetOrigin</var> [, <var>transfer</var> ])</code><dd><p>This is an alternate version of <code id=posting-messages:dom-window-postmessage-options><a href=#dom-window-postmessage-options>postMessage()</a></code> where the target origin is specified
   as a parameter. Calling <code>window.postMessage(message, target, transfer)</code> is
   equivalent to <code>window.postMessage(message, {targetOrigin,
   transfer})</code>.</dl>

  <p class=note>When posting a message to a <code id=posting-messages:window><a href=nav-history-apis.html#window>Window</a></code> of a <a id=posting-messages:browsing-context href=document-sequences.html#browsing-context>browsing context</a>
  that has just been navigated to a new <code id=posting-messages:document><a href=dom.html#document>Document</a></code> is likely to result in the message not
  receiving its intended recipient: the scripts in the target <a id=posting-messages:browsing-context-2 href=document-sequences.html#browsing-context>browsing context</a> have to
  have had time to set up listeners for the messages. Thus, for instance, in situations where a
  message is to be sent to the <code id=posting-messages:window-2><a href=nav-history-apis.html#window>Window</a></code> of newly created child <code id=posting-messages:the-iframe-element><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code>,
  authors are advised to have the child <code id=posting-messages:document-2><a href=dom.html#document>Document</a></code> post a message to their parent
  announcing their readiness to receive messages, and for the parent to wait for this message before
  beginning posting messages.</p>

  

  <p>The <dfn id=window-post-message-steps>window post message steps</dfn>, given a <var>targetWindow</var>, <var>message</var>,
  and <var>options</var>, are as follows:</p>

  <ol><li><p>Let <var>targetRealm</var> be <var>targetWindow</var>'s <a href=webappapis.html#concept-global-object-realm id=posting-messages:concept-global-object-realm>realm</a>.<li><p>Let <var>incumbentSettings</var> be the <a id=posting-messages:incumbent-settings-object href=webappapis.html#incumbent-settings-object>incumbent settings object</a>.<li><p>Let <var>targetOrigin</var> be <var>options</var>["<code id=posting-messages:dom-windowpostmessageoptions-targetorigin-2><a href=nav-history-apis.html#dom-windowpostmessageoptions-targetorigin>targetOrigin</a></code>"].<li><p>If <var>targetOrigin</var> is a single U+002F SOLIDUS character (/), then set
   <var>targetOrigin</var> to <var>incumbentSettings</var>'s <a href=webappapis.html#concept-settings-object-origin id=posting-messages:concept-settings-object-origin>origin</a>.</p>

   <li>
    <p>Otherwise, if <var>targetOrigin</var> is not a single U+002A ASTERISK character (*),
    then:</p>

    <ol><li><p>Let <var>parsedURL</var> be the result of running the <a id=posting-messages:url-parser href=https://url.spec.whatwg.org/#concept-url-parser data-x-internal=url-parser>URL parser</a> on
     <var>targetOrigin</var>.<li><p>If <var>parsedURL</var> is failure, then throw a <a id=posting-messages:syntaxerror href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a>
     <code id=posting-messages:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <var>targetOrigin</var> to <var>parsedURL</var>'s <a href=https://url.spec.whatwg.org/#concept-url-origin id=posting-messages:concept-url-origin data-x-internal=concept-url-origin>origin</a>.</ol>
   <li><p>Let <var>transfer</var> be <var>options</var>["<code id=posting-messages:dom-structuredserializeoptions-transfer-2><a href=#dom-structuredserializeoptions-transfer>transfer</a></code>"].<li><p>Let <var>serializeWithTransferResult</var> be
   <a id=posting-messages:structuredserializewithtransfer href=structured-data.html#structuredserializewithtransfer>StructuredSerializeWithTransfer</a>(<var>message</var>, <var>transfer</var>). Rethrow
   any exceptions.<li>
    <p><a id=posting-messages:queue-a-global-task href=webappapis.html#queue-a-global-task>Queue a global task</a> on the <dfn id=posted-message-task-source>posted message task source</dfn> given
    <var>targetWindow</var> to run the following steps:</p>

    <ol><li><p>If the <var>targetOrigin</var> argument is not a single literal U+002A ASTERISK character
     (*) and <var>targetWindow</var>'s <a href=nav-history-apis.html#concept-document-window id=posting-messages:concept-document-window>associated
     <code>Document</code></a>'s <a href=https://dom.spec.whatwg.org/#concept-document-origin id=posting-messages:concept-document-origin data-x-internal=concept-document-origin>origin</a> is not
     <a id=posting-messages:same-origin href=browsers.html#same-origin>same origin</a> with <var>targetOrigin</var>, then return.<li><p>Let <var>origin</var> be the <a href=browsers.html#ascii-serialisation-of-an-origin id=posting-messages:ascii-serialisation-of-an-origin>serialization</a> of <var>incumbentSettings</var>'s <a href=webappapis.html#concept-settings-object-origin id=posting-messages:concept-settings-object-origin-2>origin</a>.<li><p>Let <var>source</var> be the <code id=posting-messages:windowproxy><a href=nav-history-apis.html#windowproxy>WindowProxy</a></code> object corresponding to
     <var>incumbentSettings</var>'s <a href=webappapis.html#concept-settings-object-global id=posting-messages:concept-settings-object-global>global
     object</a> (a <code id=posting-messages:window-3><a href=nav-history-apis.html#window>Window</a></code> object).<li>
      <p>Let <var>deserializeRecord</var> be
      <a id=posting-messages:structureddeserializewithtransfer href=structured-data.html#structureddeserializewithtransfer>StructuredDeserializeWithTransfer</a>(<var>serializeWithTransferResult</var>,
      <var>targetRealm</var>).</p>

      <p>If this throws an exception, catch it, <a href=https://dom.spec.whatwg.org/#concept-event-fire id=posting-messages:concept-event-fire data-x-internal=concept-event-fire>fire an
      event</a> named <code id=posting-messages:event-messageerror><a href=indices.html#event-messageerror>messageerror</a></code> at
      <var>targetWindow</var>, using <code id=posting-messages:messageevent><a href=comms.html#messageevent>MessageEvent</a></code>, with the <code id=posting-messages:dom-messageevent-origin><a href=comms.html#dom-messageevent-origin>origin</a></code> attribute initialized to <var>origin</var> and
      the <code id=posting-messages:dom-messageevent-source><a href=comms.html#dom-messageevent-source>source</a></code> attribute initialized to
      <var>source</var>, and then return.</p>
     <li><p>Let <var>messageClone</var> be <var>deserializeRecord</var>.[[Deserialized]].<li><p>Let <var>newPorts</var> be a new <a id=posting-messages:frozen-array href=https://webidl.spec.whatwg.org/#dfn-frozen-array-type data-x-internal=frozen-array>frozen array</a> consisting of all
     <code id=posting-messages:messageport><a href=#messageport>MessagePort</a></code> objects in <var>deserializeRecord</var>.[[TransferredValues]], if any,
     maintaining their relative order.<li><p><a href=https://dom.spec.whatwg.org/#concept-event-fire id=posting-messages:concept-event-fire-2 data-x-internal=concept-event-fire>Fire an event</a> named <code id=posting-messages:event-message><a href=indices.html#event-message>message</a></code> at <var>targetWindow</var>, using
     <code id=posting-messages:messageevent-2><a href=comms.html#messageevent>MessageEvent</a></code>, with the <code id=posting-messages:dom-messageevent-origin-2><a href=comms.html#dom-messageevent-origin>origin</a></code>
     attribute initialized to <var>origin</var>, the <code id=posting-messages:dom-messageevent-source-2><a href=comms.html#dom-messageevent-source>source</a></code> attribute initialized to <var>source</var>, the
     <code id=posting-messages:dom-messageevent-data><a href=comms.html#dom-messageevent-data>data</a></code> attribute initialized to
     <var>messageClone</var>, and the <code id=posting-messages:dom-messageevent-ports><a href=comms.html#dom-messageevent-ports>ports</a></code> attribute
     initialized to <var>newPorts</var>.</ol>
   </ol>

  <p>The <code id=posting-messages:window-4><a href=nav-history-apis.html#window>Window</a></code> interface's <dfn data-dfn-for=Window id=dom-window-postmessage-options data-dfn-type=method><code>postMessage(<var>message</var>,
  <var>options</var>)</code></dfn> method steps are to run the <a href=#window-post-message-steps id=posting-messages:window-post-message-steps>window post message
  steps</a> given <a id=posting-messages:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>, <var>message</var>, and <var>options</var>.</p>

  <p>The <code id=posting-messages:window-5><a href=nav-history-apis.html#window>Window</a></code> interface's <dfn data-dfn-for=Window id=dom-window-postmessage data-dfn-type=method><code>postMessage(<var>message</var>, <var>targetOrigin</var>,
  <var>transfer</var>)</code></dfn> method steps are to run the <a href=#window-post-message-steps id=posting-messages:window-post-message-steps-2>window post message
  steps</a> given <a id=posting-messages:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>, <var>message</var>, and «[ "<code id=posting-messages:dom-windowpostmessageoptions-targetorigin-3><a href=nav-history-apis.html#dom-windowpostmessageoptions-targetorigin>targetOrigin</a></code>" →
  <var>targetOrigin</var>, "<code id=posting-messages:dom-structuredserializeoptions-transfer-3><a href=#dom-structuredserializeoptions-transfer>transfer</a></code>"
  → <var>transfer</var> ]».</p>

  




  <h3 id=channel-messaging><span class=secno>9.4</span> <dfn>Channel messaging</dfn><a href=#channel-messaging class=self-link></a></h3><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API title="The Channel Messaging API allows two separate scripts running in different browsing contexts attached to the same document (e.g., two IFrames, or the main document and an IFrame, two documents via a SharedWorker, or two workers) to communicate directly, passing messages between one another through two-way channels (or pipes) with a port at each end.">Channel_Messaging_API</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API/Using_channel_messaging title="The Channel Messaging API allows two separate scripts running in different browsing contexts attached to the same document (e.g., two <iframe> elements, the main document and a single <iframe>, or two documents via a SharedWorker) to communicate directly, passing messages between each other through two-way channels (or pipes) with a port at each end.">Channel_Messaging_API/Using_channel_messaging</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div>

  <h4 id=introduction-13><span class=secno>9.4.1</span> Introduction<a href=#introduction-13 class=self-link></a></h4>

  <p><i>This section is non-normative.</i></p>

  <p>To enable independent pieces of code (e.g. running in different <a href=document-sequences.html#browsing-context id=introduction-13:browsing-context>browsing contexts</a>) to communicate directly, authors can use <a href=#channel-messaging id=introduction-13:channel-messaging>channel
  messaging</a>.</p>

  <p>Communication channels in this mechanism are implemented as two-ways pipes, with a port at each
  end. Messages sent in one port are delivered at the other port, and vice-versa. Messages are
  delivered as DOM events, without interrupting or blocking running <a href=webappapis.html#concept-task id=introduction-13:concept-task>tasks</a>.</p>

  <p>To create a connection (two "entangled" ports), the <code>MessageChannel()</code>
  constructor is called:</p>

  <pre><code class='js'><c- a>var</c-> channel <c- o>=</c-> <c- k>new</c-> MessageChannel<c- p>();</c-></code></pre>

  <p>One of the ports is kept as the local port, and the other port is sent to the remote code, e.g.
  using <code id=introduction-13:dom-window-postmessage><a href=#dom-window-postmessage>postMessage()</a></code>:</p>

  <pre><code class='js'>otherWindow<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;hello&apos;</c-><c- p>,</c-> <c- t>&apos;https://example.com&apos;</c-><c- p>,</c-> <c- p>[</c->channel<c- p>.</c->port2<c- p>]);</c-></code></pre>

  <p>To send messages, the <code id=introduction-13:dom-messageport-postmessage><a href=#dom-messageport-postmessage>postMessage()</a></code> method on
  the port is used:</p>

  <pre><code class='js'>channel<c- p>.</c->port1<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;hello&apos;</c-><c- p>);</c-></code></pre>

  <p>To receive messages, one listens to <code id=introduction-13:event-message><a href=indices.html#event-message>message</a></code> events:</p>

  <pre><code class='js'>channel<c- p>.</c->port1<c- p>.</c->onmessage <c- o>=</c-> handleMessage<c- p>;</c->
<c- a>function</c-> handleMessage<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  <c- c1>// message is in event.data</c->
  <c- c1>// ...</c->
<c- p>}</c-></code></pre>

  <p>Data sent on a port can be structured data; for example here an array of strings is passed on a
  <code id=introduction-13:messageport><a href=#messageport>MessagePort</a></code>:</p>

  <pre><code class='js'>port1<c- p>.</c->postMessage<c- p>([</c-><c- t>&apos;hello&apos;</c-><c- p>,</c-> <c- t>&apos;world&apos;</c-><c- p>]);</c-></code></pre>


  <h5 id=examples-5><span class=secno>9.4.1.1</span> Examples<a href=#examples-5 class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <div class=example>

   <p>In this example, two JavaScript libraries are connected to each other using
   <code id=examples-5:messageport><a href=#messageport>MessagePort</a></code>s. This allows the libraries to later be hosted in different frames, or
   in <code id=examples-5:worker><a href=workers.html#worker>Worker</a></code> objects, without any change to the APIs.</p>

   <pre><code class='html'><c- p>&lt;</c-><c- f>script</c-> <c- e>src</c-><c- o>=</c-><c- s>&quot;contacts.js&quot;</c-><c- p>&gt;&lt;/</c-><c- f>script</c-><c- p>&gt;</c-> <c- c>&lt;!-- exposes a contacts object --&gt;</c->
<c- p>&lt;</c-><c- f>script</c-> <c- e>src</c-><c- o>=</c-><c- s>&quot;compose-mail.js&quot;</c-><c- p>&gt;&lt;/</c-><c- f>script</c-><c- p>&gt;</c-> <c- c>&lt;!-- exposes a composer object --&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
 <c- a>var</c-> channel <c- o>=</c-> <c- k>new</c-> MessageChannel<c- p>();</c->
 composer<c- p>.</c->addContactsProvider<c- p>(</c->channel<c- p>.</c->port1<c- p>);</c->
 contacts<c- p>.</c->registerConsumer<c- p>(</c->channel<c- p>.</c->port2<c- p>);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c-></code></pre>

   <p>Here's what the "addContactsProvider()" function's implementation could look like:</p>

   <pre><code class='js'><c- a>function</c-> addContactsProvider<c- p>(</c->port<c- p>)</c-> <c- p>{</c->
  port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
    <c- k>switch</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->messageType<c- p>)</c-> <c- p>{</c->
      <c- k>case</c-> <c- t>&apos;search-result&apos;</c-><c- o>:</c-> handleSearchResult<c- p>(</c->event<c- p>.</c->data<c- p>.</c->results<c- p>);</c-> <c- k>break</c-><c- p>;</c->
      <c- k>case</c-> <c- t>&apos;search-done&apos;</c-><c- o>:</c-> handleSearchDone<c- p>();</c-> <c- k>break</c-><c- p>;</c->
      <c- k>case</c-> <c- t>&apos;search-error&apos;</c-><c- o>:</c-> handleSearchError<c- p>(</c->event<c- p>.</c->data<c- p>.</c->message<c- p>);</c-> <c- k>break</c-><c- p>;</c->
      <c- c1>// ...</c->
    <c- p>}</c->
  <c- p>};</c->
<c- p>};</c-></code></pre>

   <p>Alternatively, it could be implemented as follows:</p>

   <pre><code class='js'><c- a>function</c-> addContactsProvider<c- p>(</c->port<c- p>)</c-> <c- p>{</c->
  port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->messageType <c- o>==</c-> <c- t>&apos;search-result&apos;</c-><c- p>)</c->
      handleSearchResult<c- p>(</c->event<c- p>.</c->data<c- p>.</c->results<c- p>);</c->
  <c- p>});</c->
  port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->messageType <c- o>==</c-> <c- t>&apos;search-done&apos;</c-><c- p>)</c->
      handleSearchDone<c- p>();</c->
  <c- p>});</c->
  port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->messageType <c- o>==</c-> <c- t>&apos;search-error&apos;</c-><c- p>)</c->
      handleSearchError<c- p>(</c->event<c- p>.</c->data<c- p>.</c->message<c- p>);</c->
  <c- p>});</c->
  <c- c1>// ...</c->
  port<c- p>.</c->start<c- p>();</c->
<c- p>};</c-></code></pre>

   <p>The key difference is that when using <code id=examples-5:dom-eventtarget-addeventlistener><a data-x-internal=dom-eventtarget-addeventlistener href=https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener>addEventListener()</a></code>, the <code id=examples-5:dom-messageport-start><a href=#dom-messageport-start>start()</a></code> method must also be invoked. When using <code id=examples-5:handler-messageeventtarget-onmessage><a href=#handler-messageeventtarget-onmessage>onmessage</a></code>, the call to <code id=examples-5:dom-messageport-start-2><a href=#dom-messageport-start>start()</a></code> is implied.</p>

   <p>The <code id=examples-5:dom-messageport-start-3><a href=#dom-messageport-start>start()</a></code> method, whether called explicitly or
   implicitly (by setting <code id=examples-5:handler-messageeventtarget-onmessage-2><a href=#handler-messageeventtarget-onmessage>onmessage</a></code>),
   starts the flow of messages: messages posted on message ports are initially paused, so that they
   don't get dropped on the floor before the script has had a chance to set up its handlers.</p>

  </div>


  <h5 id=ports-as-the-basis-of-an-object-capability-model-on-the-web><span class=secno>9.4.1.2</span> Ports as the basis of an object-capability model on the web<a href=#ports-as-the-basis-of-an-object-capability-model-on-the-web class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>Ports can be viewed as a way to expose limited capabilities (in the object-capability model
  sense) to other actors in the system. This can either be a weak capability system, where the ports
  are merely used as a convenient model within a particular origin, or as a strong capability model,
  where they are provided by one origin <var>provider</var> as the only mechanism by which
  another origin <var>consumer</var> can effect change in or obtain information from <var>provider</var>.</p>

  <p>For example, consider a situation in which a social web site embeds in one <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code>
  the user's email contacts provider (an address book site, from a second origin), and in a second
  <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-2><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> a game (from a third origin). The outer social site and the game in the second
  <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-3><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> cannot access anything inside the first <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-4><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code>; together they can
  only:</p>

  <ul><li><p><a id=ports-as-the-basis-of-an-object-capability-model-on-the-web:navigate href=browsing-the-web.html#navigate>Navigate</a> the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-5><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> to a new <a id=ports-as-the-basis-of-an-object-capability-model-on-the-web:url href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a>, such as the same
   <a id=ports-as-the-basis-of-an-object-capability-model-on-the-web:url-2 href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a> but with a different <a href=https://url.spec.whatwg.org/#concept-url-fragment id=ports-as-the-basis-of-an-object-capability-model-on-the-web:concept-url-fragment data-x-internal=concept-url-fragment>fragment</a>,
   causing the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:window><a href=nav-history-apis.html#window>Window</a></code> in the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-6><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> to receive a <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:event-hashchange><a href=indices.html#event-hashchange>hashchange</a></code> event.<li><p>Resize the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-7><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code>, causing the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:window-2><a href=nav-history-apis.html#window>Window</a></code> in the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-8><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code>
   to receive a <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:event-resize><a data-x-internal=event-resize href=https://drafts.csswg.org/cssom-view/#eventdef-window-resize>resize</a></code> event.<li><p>Send a <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:event-message><a href=indices.html#event-message>message</a></code> event to the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:window-3><a href=nav-history-apis.html#window>Window</a></code> in the
   <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:the-iframe-element-9><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> using the <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:dom-window-postmessage><a href=#dom-window-postmessage>window.postMessage()</a></code>
   API.</ul>

  <p>The contacts provider can use these methods, most particularly the third one, to provide an API
  that can be accessed by other origins to manipulate the user's address book. For example, it could
  respond to a message "<code>add-contact Guillaume Tell
  &lt;tell@pomme.example.net></code>" by adding the given person and email address to the user's
  address book.</p>

  <p>To avoid any site on the web being able to manipulate the user's contacts, the contacts
  provider might only allow certain trusted sites, such as the social site, to do this.</p>

  <p>Now suppose the game wanted to add a contact to the user's address book, and that the social
  site was willing to allow it to do so on its behalf, essentially "sharing" the trust that the
  contacts provider had with the social site. There are several ways it could do this; most simply,
  it could just proxy messages between the game site and the contacts site. However, this solution
  has a number of difficulties: it requires the social site to either completely trust the game site
  not to abuse the privilege, or it requires that the social site verify each request to make sure
  it's not a request that it doesn't want to allow (such as adding multiple contacts, reading the
  contacts, or deleting them); it also requires some additional complexity if there's ever the
  possibility of multiple games simultaneously trying to interact with the contacts provider.</p>

  <p>Using message channels and <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:messageport><a href=#messageport>MessagePort</a></code> objects, however, all of these problems can
  go away. When the game tells the social site that it wants to add a contact, the social site can
  ask the contacts provider not for it to add a contact, but for the <em>capability</em> to add a
  single contact. The contacts provider then creates a pair of <code id=ports-as-the-basis-of-an-object-capability-model-on-the-web:messageport-2><a href=#messageport>MessagePort</a></code> objects, and
  sends one of them back to the social site, who forwards it on to the game. The game and the
  contacts provider then have a direct connection, and the contacts provider knows to only honor a
  single "add contact" request, nothing else. In other words, the game has been granted the
  capability to add a single contact.</p>


  <h5 id=ports-as-the-basis-of-abstracting-out-service-implementations><span class=secno>9.4.1.3</span> Ports as the basis of abstracting out service implementations<a href=#ports-as-the-basis-of-abstracting-out-service-implementations class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>Continuing the example from the previous section, consider the contacts provider in particular.
  While an initial implementation might have simply used <code id=ports-as-the-basis-of-abstracting-out-service-implementations:xmlhttprequest><a data-x-internal=xmlhttprequest href=https://xhr.spec.whatwg.org/#xmlhttprequest>XMLHttpRequest</a></code> objects in the
  service's <code id=ports-as-the-basis-of-abstracting-out-service-implementations:the-iframe-element><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code>, an evolution of the service might instead want to use a <a href=workers.html#sharedworker id=ports-as-the-basis-of-abstracting-out-service-implementations:sharedworker>shared worker</a> with a single <code id=ports-as-the-basis-of-abstracting-out-service-implementations:websocket-2><a data-x-internal=websocket-2 href=https://websockets.spec.whatwg.org/#websocket>WebSocket</a></code> connection.</p>

  <p>If the initial design used <code id=ports-as-the-basis-of-abstracting-out-service-implementations:messageport><a href=#messageport>MessagePort</a></code> objects to grant capabilities, or even just
  to allow multiple simultaneous independent sessions, the service implementation can switch from
  the <code id=ports-as-the-basis-of-abstracting-out-service-implementations:xmlhttprequest-2><a data-x-internal=xmlhttprequest href=https://xhr.spec.whatwg.org/#xmlhttprequest>XMLHttpRequest</a></code>s-in-each-<code id=ports-as-the-basis-of-abstracting-out-service-implementations:the-iframe-element-2><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> model to the
  shared-<code id=ports-as-the-basis-of-abstracting-out-service-implementations:websocket-2-2><a data-x-internal=websocket-2 href=https://websockets.spec.whatwg.org/#websocket>WebSocket</a></code> model without changing the API at all: the ports on the service
  provider side can all be forwarded to the shared worker without it affecting the users of the API
  in the slightest.</p>



  <h4 id=message-channels><span class=secno>9.4.2</span> Message channels<a href=#message-channels class=self-link></a></h4><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel title="The MessageChannel interface of the Channel Messaging API allows us to create a new message channel and send data through it via its two MessagePort properties.">MessageChannel</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div>

  <pre><code class='idl'>[<c- g>Exposed</c->=(<c- n>Window</c->,<c- n>Worker</c->)]
<c- b>interface</c-> <dfn id='messagechannel' data-dfn-type='interface'><c- g>MessageChannel</c-></dfn> {
  <a href='#dom-messagechannel' id='message-channels:dom-messagechannel'><c- g>constructor</c-></a>();

  <c- b>readonly</c-> <c- b>attribute</c-> <a href='#messageport' id='message-channels:messageport'><c- n>MessagePort</c-></a> <a href='#dom-messagechannel-port1' id='message-channels:dom-messagechannel-port1'><c- g>port1</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <a href='#messageport' id='message-channels:messageport-2'><c- n>MessagePort</c-></a> <a href='#dom-messagechannel-port2' id='message-channels:dom-messagechannel-port2'><c- g>port2</c-></a>;
};</code></pre>

  <dl class=domintro><dt><code><var>channel</var> = new <a href=#dom-messagechannel id=dom-messagechannel-dev>MessageChannel</a>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel/MessageChannel title="The MessageChannel() constructor of the MessageChannel interface returns a new MessageChannel object with two new MessagePort objects.">MessageChannel/MessageChannel</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd>
    <p>Returns a new <code id=message-channels:messagechannel><a href=#messagechannel>MessageChannel</a></code> object with two new <code id=message-channels:messageport-3><a href=#messageport>MessagePort</a></code>
    objects.</p>
   <dt><code><var>channel</var>.<a href=#dom-messagechannel-port1 id=dom-messagechannel-port1-dev>port1</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel/port1 title="The port1 read-only property of the MessageChannel interface returns the first port of the message channel — the port attached to the context that originated the channel.">MessageChannel/port1</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd><p>Returns the first <code id=message-channels:messageport-4><a href=#messageport>MessagePort</a></code> object.<dt><code><var>channel</var>.<a href=#dom-messagechannel-port2 id=dom-messagechannel-port2-dev>port2</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel/port2 title="The port2 read-only property of the MessageChannel interface returns the second port of the message channel — the port attached to the context at the other end of the channel, which the message is initially sent to.">MessageChannel/port2</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd><p>Returns the second <code id=message-channels:messageport-5><a href=#messageport>MessagePort</a></code> object.</dl>

  

  <p>A <code id=message-channels:messagechannel-2><a href=#messagechannel>MessageChannel</a></code> object has an associated <dfn id=port-1>port 1</dfn> and an associated
  <dfn id=port-2>port 2</dfn>, both <code id=message-channels:messageport-6><a href=#messageport>MessagePort</a></code> objects.</p>

  <p>The <dfn id=dom-messagechannel><code>new MessageChannel()</code></dfn> constructor steps
  are:</p>

  <ol><li><p>Set <a id=message-channels:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#port-1 id=message-channels:port-1>port 1</a> to a <a id=message-channels:new href=https://webidl.spec.whatwg.org/#new data-x-internal=new>new</a>
   <code id=message-channels:messageport-7><a href=#messageport>MessagePort</a></code> in <a id=message-channels:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=webappapis.html#concept-relevant-realm id=message-channels:concept-relevant-realm>relevant
   realm</a>.<li><p>Set <a id=message-channels:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#port-2 id=message-channels:port-2>port 2</a> to a <a id=message-channels:new-2 href=https://webidl.spec.whatwg.org/#new data-x-internal=new>new</a>
   <code id=message-channels:messageport-8><a href=#messageport>MessagePort</a></code> in <a id=message-channels:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=webappapis.html#concept-relevant-realm id=message-channels:concept-relevant-realm-2>relevant
   realm</a>.<li><p><a href=#entangle id=message-channels:entangle>Entangle</a> <a id=message-channels:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#port-1 id=message-channels:port-1-2>port 1</a> and <a id=message-channels:this-6 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s
   <a href=#port-2 id=message-channels:port-2-2>port 2</a>.</ol>

  <p>The <dfn data-dfn-for=MessageChannel id=dom-messagechannel-port1 data-dfn-type=attribute><code>port1</code></dfn> getter steps are to return
  <a id=message-channels:this-7 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#port-1 id=message-channels:port-1-3>port 1</a>.</p>

  <p>The <dfn data-dfn-for=MessageChannel id=dom-messagechannel-port2 data-dfn-type=attribute><code>port2</code></dfn> getter steps are to return
  <a id=message-channels:this-8 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#port-2 id=message-channels:port-2-3>port 2</a>.</p>

  

  <h4 id=the-messageeventtarget-mixin><span class=secno>9.4.3</span> <span id=the-messageeventtarget-abstract-interface></span>The
  <code id=the-messageeventtarget-mixin:messageeventtarget><a href=#messageeventtarget>MessageEventTarget</a></code> mixin<a href=#the-messageeventtarget-mixin class=self-link></a></h4>
  

  <pre><code class='idl'><c- b>interface</c-> <c- b>mixin</c-> <dfn id='messageeventtarget' data-dfn-type='interface'><c- g>MessageEventTarget</c-></dfn> {
  <c- b>attribute</c-> <a id='the-messageeventtarget-mixin:eventhandler' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-messageeventtarget-onmessage' id='the-messageeventtarget-mixin:handler-messageeventtarget-onmessage'><c- g>onmessage</c-></a>;
  <c- b>attribute</c-> <a id='the-messageeventtarget-mixin:eventhandler-2' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-messageeventtarget-onmessageerror' id='the-messageeventtarget-mixin:handler-messageeventtarget-onmessageerror'><c- g>onmessageerror</c-></a>;
};</code></pre>

   <p>The following are the <a id=the-messageeventtarget-mixin:event-handlers href=webappapis.html#event-handlers>event handlers</a> (and their corresponding <a href=webappapis.html#event-handler-event-type id=the-messageeventtarget-mixin:event-handler-event-type>event handler event types</a>) that must be supported,
   as <a id=the-messageeventtarget-mixin:event-handler-idl-attributes href=webappapis.html#event-handler-idl-attributes>event handler IDL attributes</a>, by objects implementing the
   <code id=the-messageeventtarget-mixin:messageeventtarget-2><a href=#messageeventtarget>MessageEventTarget</a></code> interface:</p>

   <table><thead><tr><th><a href=webappapis.html#event-handlers id=the-messageeventtarget-mixin:event-handlers-2>Event handler</a> <th><a id=the-messageeventtarget-mixin:event-handler-event-type-2 href=webappapis.html#event-handler-event-type>Event handler event type</a>
    <tbody><tr><td><span id=handler-messageport-onmessage></span><span id=handler-worker-onmessage></span><span id=handler-dedicatedworkerglobalscope-onmessage></span><dfn data-dfn-for=MessageEventTarget id=handler-messageeventtarget-onmessage data-dfn-type=attribute><code>onmessage</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/message_event title="The message event is fired on a MessagePort object when a message arrives on that channel.">MessagePort/message_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11.5+</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/message_event title="The message event is fired on a DedicatedWorkerGlobalScope object when the worker receives a message from its parent (i.e. when the parent sends a message using Worker.postMessage()).">DedicatedWorkerGlobalScope/message_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11.5+</span></span></div></div></div><td> <code id=the-messageeventtarget-mixin:event-message><a href=indices.html#event-message>message</a></code>
     <tr><td><span id=handler-messageport-onmessageerror></span><span id=handler-worker-onmessageerror></span><span id=handler-dedicatedworkerglobalscope-onmessageerror></span><dfn data-dfn-for=MessageEventTarget id=handler-messageeventtarget-onmessageerror data-dfn-type=attribute><code>onmessageerror</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/messageerror_event title="The messageerror event is fired on a MessagePort object when it receives a message that can't be deserialized.">MessagePort/messageerror_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>57+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>60+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>18</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>47+</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/messageerror_event title="The messageerror event is fired on a DedicatedWorkerGlobalScope object when it receives a message that can't be deserialized.">DedicatedWorkerGlobalScope/messageerror_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>57+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>60+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>18</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>47+</span></span></div></div></div><td> <code id=the-messageeventtarget-mixin:event-messageerror><a href=indices.html#event-messageerror>messageerror</a></code>
   </table>

  <h4 id=message-ports><span class=secno>9.4.4</span> Message ports<a href=#message-ports class=self-link></a></h4><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessagePort title="The MessagePort interface of the Channel Messaging API represents one of the two ports of a MessageChannel, allowing messages to be sent from one port and listening out for them arriving at the other.">MessagePort</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div>

  <p>Each channel has two message ports. Data sent through one port is received by the other port,
  and vice versa.</p>

  <pre><code class='idl'>[<c- g>Exposed</c->=(<c- n>Window</c->,<c- n>Worker</c->,<c- n>AudioWorklet</c->), <a id='message-ports:transferable' href='structured-data.html#transferable'><c- g>Transferable</c-></a>]
<c- b>interface</c-> <dfn id='messageport' data-dfn-type='interface'><c- g>MessagePort</c-></dfn> : <a id='message-ports:eventtarget' href='https://dom.spec.whatwg.org/#interface-eventtarget' data-x-internal='eventtarget'><c- n>EventTarget</c-></a> {
  <c- b>undefined</c-> <a href='#dom-messageport-postmessage' id='message-ports:dom-messageport-postmessage'><c- g>postMessage</c-></a>(<c- b>any</c-> <c- g>message</c->, <c- b>sequence</c->&lt;<a href='https://webidl.spec.whatwg.org/#idl-object' id='message-ports:idl-object' data-x-internal='idl-object'><c- b>object</c-></a>&gt; <c- g>transfer</c->);
  <c- b>undefined</c-> <a href='#dom-messageport-postmessage-options' id='message-ports:dom-messageport-postmessage-options'><c- g>postMessage</c-></a>(<c- b>any</c-> <c- g>message</c->, <c- b>optional</c-> <a href='#structuredserializeoptions' id='message-ports:structuredserializeoptions'><c- n>StructuredSerializeOptions</c-></a> <c- g>options</c-> = {});
  <c- b>undefined</c-> <a href='#dom-messageport-start' id='message-ports:dom-messageport-start'><c- g>start</c-></a>();
  <c- b>undefined</c-> <a href='#dom-messageport-close' id='message-ports:dom-messageport-close'><c- g>close</c-></a>();

  // event handlers
  <c- b>attribute</c-> <a id='message-ports:eventhandler' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-messageport-onclose' id='message-ports:handler-messageport-onclose'><c- g>onclose</c-></a>;
};

<a href='#messageport' id='message-ports:messageport'><c- n>MessagePort</c-></a> <c- b>includes</c-> <a href='#messageeventtarget' id='message-ports:messageeventtarget'><c- n>MessageEventTarget</c-></a>;

<c- b>dictionary</c-> <dfn id='structuredserializeoptions' data-dfn-type='dictionary'><c- g>StructuredSerializeOptions</c-></dfn> {
  <c- b>sequence</c->&lt;<a href='https://webidl.spec.whatwg.org/#idl-object' id='message-ports:idl-object-2' data-x-internal='idl-object'><c- b>object</c-></a>&gt; <dfn data-dfn-for='StructuredSerializeOptions' id='dom-structuredserializeoptions-transfer' data-dfn-type='dict-member'><c- g>transfer</c-></dfn> = [];
};</code></pre>

  <dl class=domintro><dt><code><var>port</var>.<a href=#dom-messageport-postmessage id=dom-messageport-postmessage-dev>postMessage</a>(<var>message</var> [, <var>transfer</var>])</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage title="The postMessage() method of the MessagePort interface sends a message from the port, and optionally, transfers ownership of objects to other browsing contexts.">MessagePort/postMessage</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dt><code><var>port</var>.<a href=#dom-messageport-postmessage-options id=dom-messageport-postmessage-options-dev>postMessage</a>(<var>message</var> [, { <span>transfer</span> }])</code><dd>
    <p>Posts a message through the channel. Objects listed in <var>transfer</var> are transferred,
    not just cloned, meaning that they are no longer usable on the sending side.</p>

    <p>Throws a <a id=message-ports:datacloneerror href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=message-ports:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if
    <var>transfer</var> contains duplicate objects or <var>port</var>, or if <var>message</var>
    could not be cloned.</p>
   <dt><code><var>port</var>.<a href=#dom-messageport-start id=dom-messageport-start-dev>start</a>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/start title="The start() method of the MessagePort interface starts the sending of messages queued on the port. This method is only needed when using EventTarget.addEventListener; it is implied when using onmessage.">MessagePort/start</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd><p>Begins dispatching messages received on the port.<dt><code><var>port</var>.<a href=#dom-messageport-close id=dom-messageport-close-dev>close</a>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/close title="The close() method of the MessagePort interface disconnects the port, so it is no longer active. This stops the flow of messages to that port.">MessagePort/close</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>41+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd><p>Disconnects the port, so that it is no longer active.</dl>

  

  <p>Each <code id=message-ports:messageport-2><a href=#messageport>MessagePort</a></code> object has a <dfn id=message-event-target>message event target</dfn> (a
  <code id=message-ports:messageeventtarget-2><a href=#messageeventtarget>MessageEventTarget</a></code>), to which the <code id=message-ports:event-message><a href=indices.html#event-message>message</a></code> and <code id=message-ports:event-messageerror><a href=indices.html#event-messageerror>messageerror</a></code> events are dispatched. Unless otherwise
  specified, it defaults to the <code id=message-ports:messageport-3><a href=#messageport>MessagePort</a></code> object itself.</p>

  <p>Each <code id=message-ports:messageport-4><a href=#messageport>MessagePort</a></code> object can be entangled with another (a symmetric relationship).
  Each <code id=message-ports:messageport-5><a href=#messageport>MessagePort</a></code> object also has a <a id=message-ports:task-source href=webappapis.html#task-source>task source</a> called the <dfn id=port-message-queue>port
  message queue</dfn>, initially empty. A <a href=#port-message-queue id=message-ports:port-message-queue>port message queue</a> can be enabled or
  disabled, and is initially disabled. Once enabled, a port can never be disabled again (though
  messages in the queue can get moved to another queue or removed altogether, which has much the
  same effect). A <code id=message-ports:messageport-6><a href=#messageport>MessagePort</a></code> also has a <dfn id=has-been-shipped>has been shipped</dfn> flag, which must
  initially be false.</p>

  <p>When a port's <a href=#port-message-queue id=message-ports:port-message-queue-2>port message queue</a> is enabled, the <a id=message-ports:event-loop href=webappapis.html#event-loop>event loop</a> must use
  it as one of its <a href=webappapis.html#task-source id=message-ports:task-source-2>task sources</a>. When a port's <a id=message-ports:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant
  global object</a> is a <code id=message-ports:window><a href=nav-history-apis.html#window>Window</a></code>, all <a href=webappapis.html#concept-task id=message-ports:concept-task>tasks</a> <a href=webappapis.html#queue-a-task id=message-ports:queue-a-task>queued</a> on its <a href=#port-message-queue id=message-ports:port-message-queue-3>port message queue</a> must be associated with
  the port's <a id=message-ports:concept-relevant-global-2 href=webappapis.html#concept-relevant-global>relevant global object</a>'s <a href=nav-history-apis.html#concept-document-window id=message-ports:concept-document-window>associated
  <code>Document</code></a>.</p>

  <p class=note>If the document is <a id=message-ports:fully-active href=document-sequences.html#fully-active>fully active</a>, but the event listeners were all
  created in the context of documents that are <em>not</em> <a id=message-ports:fully-active-2 href=document-sequences.html#fully-active>fully active</a>, then the
  messages will not be received unless and until the documents become <a id=message-ports:fully-active-3 href=document-sequences.html#fully-active>fully active</a>
  again.</p>

  <p>Each <a id=message-ports:event-loop-2 href=webappapis.html#event-loop>event loop</a> has a <a id=message-ports:task-source-3 href=webappapis.html#task-source>task source</a> called the <dfn id=unshipped-port-message-queue>unshipped port
  message queue</dfn>. This is a virtual <a id=message-ports:task-source-4 href=webappapis.html#task-source>task source</a>: it must act as if it contained
  the <a href=webappapis.html#concept-task id=message-ports:concept-task-2>tasks</a> of each <a href=#port-message-queue id=message-ports:port-message-queue-4>port message queue</a> of each
  <code id=message-ports:messageport-7><a href=#messageport>MessagePort</a></code> whose <a href=#has-been-shipped id=message-ports:has-been-shipped>has been shipped</a> flag is false, whose <a href=#port-message-queue id=message-ports:port-message-queue-5>port
  message queue</a> is enabled, and whose <a id=message-ports:relevant-agent href=webappapis.html#relevant-agent>relevant agent</a>'s <a href=webappapis.html#concept-agent-event-loop id=message-ports:concept-agent-event-loop>event loop</a> is that <a id=message-ports:event-loop-3 href=webappapis.html#event-loop>event loop</a>, in the order
  in which they were added to their respective <a id=message-ports:task-source-5 href=webappapis.html#task-source>task source</a>. When a <a href=webappapis.html#concept-task id=message-ports:concept-task-3>task</a> would be removed from the <a href=#unshipped-port-message-queue id=message-ports:unshipped-port-message-queue>unshipped port message
  queue</a>, it must instead be removed from its <a href=#port-message-queue id=message-ports:port-message-queue-6>port message queue</a>.</p>

  <p>When a <code id=message-ports:messageport-8><a href=#messageport>MessagePort</a></code>'s <a href=#has-been-shipped id=message-ports:has-been-shipped-2>has been shipped</a> flag is false, its <a href=#port-message-queue id=message-ports:port-message-queue-7>port
  message queue</a> must be ignored for the purposes of the <a id=message-ports:event-loop-4 href=webappapis.html#event-loop>event loop</a>. (The
  <a href=#unshipped-port-message-queue id=message-ports:unshipped-port-message-queue-2>unshipped port message queue</a> is used instead.)</p>

  <p class=note>The <a href=#has-been-shipped id=message-ports:has-been-shipped-3>has been shipped</a> flag is set to true when a port, its twin, or
  the object it was cloned from, is or has been transferred. When a <code id=message-ports:messageport-9><a href=#messageport>MessagePort</a></code>'s
  <a href=#has-been-shipped id=message-ports:has-been-shipped-4>has been shipped</a> flag is true, its <a href=#port-message-queue id=message-ports:port-message-queue-8>port message queue</a> acts as a
  first-class <a id=message-ports:task-source-6 href=webappapis.html#task-source>task source</a>, unaffected to any <a href=#unshipped-port-message-queue id=message-ports:unshipped-port-message-queue-3>unshipped port message
  queue</a>.</p>

  <p>When the user agent is to <dfn id=entangle>entangle</dfn> two <code id=message-ports:messageport-10><a href=#messageport>MessagePort</a></code> objects, it must run
  the following steps:</p>

  <ol><li>
    <p>If one of the ports is already entangled, then disentangle it and the port that it was
    entangled with.</p>

    <p class=note>If those two previously entangled ports were the two ports of a
    <code id=message-ports:messagechannel><a href=#messagechannel>MessageChannel</a></code> object, then that <code id=message-ports:messagechannel-2><a href=#messagechannel>MessageChannel</a></code> object no longer
    represents an actual channel: the two ports in that object are no longer entangled.</p>
   <li>
    <p>Associate the two ports to be entangled, so that they form the two parts of a new channel.
    (There is no <code id=message-ports:messagechannel-3><a href=#messagechannel>MessageChannel</a></code> object that represents this channel.)</p>

    <p>Two ports <var>A</var> and <var>B</var> that have gone through this step
    are now said to be entangled; one is entangled to the other, and vice versa.</p>

    <p class=note>While this specification describes this process as instantaneous,
    implementations are more likely to implement it via message passing. As with all algorithms, the
    key is "merely" that the end result be indistinguishable, in a black-box sense, from the
    specification.</p>
   </ol>

  <p>The <dfn id=disentangle>disentangle</dfn> steps, given a <code id=message-ports:messageport-11><a href=#messageport>MessagePort</a></code> <var>initiatorPort</var>
  which initiates disentangling, are as follows:</p>

  <ol><li><p>Let <var>otherPort</var> be the <code id=message-ports:messageport-12><a href=#messageport>MessagePort</a></code> which <var>initiatorPort</var>
   was entangled with.<li><p><a id=message-ports:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>otherPort</var> exists.<li><p>Disentangle <var>initiatorPort</var> and <var>otherPort</var>, so that they are no longer
   entangled or associated with each other.<li><p><a href=https://dom.spec.whatwg.org/#concept-event-fire id=message-ports:concept-event-fire data-x-internal=concept-event-fire>Fire an event</a> named <code id=message-ports:event-close><a href=indices.html#event-close>close</a></code> at <var>otherPort</var>.</ol>

  <div class=note>
   <p>The <code id=message-ports:event-close-2><a href=indices.html#event-close>close</a></code> event will be fired even if the port is not
   explicitly closed. The cases where this event is dispatched are:</p>

   <ul><li>the <code id=message-ports:dom-messageport-close-2><a href=#dom-messageport-close>close()</a></code> method was called;<li>the <code id=message-ports:document><a href=dom.html#document>Document</a></code> was <a href=document-lifecycle.html#destroy-a-document id=message-ports:destroy-a-document>destroyed</a>; or<li>the <code id=message-ports:messageport-13><a href=#messageport>MessagePort</a></code> was <a href=#ports-and-garbage-collection>garbage
    collected</a>.</ul>

   <p>We only dispatch the event on <var>otherPort</var> because <var>initiatorPort</var> explicitly
   triggered the close, its <code id=message-ports:document-2><a href=dom.html#document>Document</a></code> no longer exists, or it was already garbage
   collected, as described above.</p>
  </div>

  <hr>

  <p id=transferMessagePort><code id=message-ports:messageport-14><a href=#messageport>MessagePort</a></code> objects are <a id=message-ports:transferable-objects href=structured-data.html#transferable-objects>transferable
  objects</a>. Their <a id=message-ports:transfer-steps href=structured-data.html#transfer-steps>transfer steps</a>, given <var>value</var> and
  <var>dataHolder</var>, are:</p>

  <ol><li><p>Set <var>value</var>'s <a href=#has-been-shipped id=message-ports:has-been-shipped-5>has been shipped</a> flag to true.<li><p>Set <var>dataHolder</var>.[[PortMessageQueue]] to <var>value</var>'s <a href=#port-message-queue id=message-ports:port-message-queue-9>port message
   queue</a>.<li>
    <p>If <var>value</var> is entangled with another port <var>remotePort</var>, then:</p>

    <ol><li><p>Set <var>remotePort</var>'s <a href=#has-been-shipped id=message-ports:has-been-shipped-6>has been shipped</a> flag to true.<li><p>Set <var>dataHolder</var>.[[RemotePort]] to <var>remotePort</var>.</ol>
   <li><p>Otherwise, set <var>dataHolder</var>.[[RemotePort]] to null.</ol>

  <p>Their <a id=message-ports:transfer-receiving-steps href=structured-data.html#transfer-receiving-steps>transfer-receiving steps</a>, given <var>dataHolder</var> and <var>value</var>,
  are:</p>

  <ol><li><p>Set <var>value</var>'s <a href=#has-been-shipped id=message-ports:has-been-shipped-7>has been shipped</a> flag to true.<li><p>Move all the <a href=webappapis.html#concept-task id=message-ports:concept-task-4>tasks</a> that are to fire <code id=message-ports:event-message-2><a href=indices.html#event-message>message</a></code> events in <var>dataHolder</var>.[[PortMessageQueue]] to the
   <a href=#port-message-queue id=message-ports:port-message-queue-10>port message queue</a> of <var>value</var>, if any, leaving <var>value</var>'s
   <a href=#port-message-queue id=message-ports:port-message-queue-11>port message queue</a> in its initial disabled state, and, if <var>value</var>'s
   <a id=message-ports:concept-relevant-global-3 href=webappapis.html#concept-relevant-global>relevant global object</a> is a <code id=message-ports:window-2><a href=nav-history-apis.html#window>Window</a></code>, associating the moved <a href=webappapis.html#concept-task id=message-ports:concept-task-5>tasks</a> with <var>value</var>'s <a id=message-ports:concept-relevant-global-4 href=webappapis.html#concept-relevant-global>relevant global object</a>'s
   <a href=nav-history-apis.html#concept-document-window id=message-ports:concept-document-window-2>associated <code>Document</code></a>.<li><p>If <var>dataHolder</var>.[[RemotePort]] is not null, then <a href=#entangle id=message-ports:entangle>entangle</a>
   <var>dataHolder</var>.[[RemotePort]] and <var>value</var>. (This will disentangle
   <var>dataHolder</var>.[[RemotePort]] from the original port that was transferred.)</ol>

  <hr>

  <p>The <dfn id=message-port-post-message-steps>message port post message steps</dfn>, given <var>sourcePort</var>,
  <var>targetPort</var>, <var>message</var>, and <var>options</var> are as follows:</p>

  <ol><li><p>Let <var>transfer</var> be <var>options</var>["<code id=message-ports:dom-structuredserializeoptions-transfer><a href=#dom-structuredserializeoptions-transfer>transfer</a></code>"].<li><p>If <var>transfer</var> <a href=https://infra.spec.whatwg.org/#list-contain id=message-ports:list-contains data-x-internal=list-contains>contains</a>
   <var>sourcePort</var>, then throw a <a id=message-ports:datacloneerror-2 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a>
   <code id=message-ports:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>doomed</var> be false.<li><p>If <var>targetPort</var> is not null and <var>transfer</var> <a href=https://infra.spec.whatwg.org/#list-contain id=message-ports:list-contains-2 data-x-internal=list-contains>contains</a> <var>targetPort</var>, then set <var>doomed</var> to true and
   optionally report to a developer console that the target port was posted to itself, causing the
   communication channel to be lost.<li><p>Let <var>serializeWithTransferResult</var> be
   <a id=message-ports:structuredserializewithtransfer href=structured-data.html#structuredserializewithtransfer>StructuredSerializeWithTransfer</a>(<var>message</var>, <var>transfer</var>). Rethrow
   any exceptions.<li><p>If <var>targetPort</var> is null, or if <var>doomed</var> is true, then return.<li>
    <p>Add a <a href=webappapis.html#concept-task id=message-ports:concept-task-6>task</a> that runs the following steps to the <a href=#port-message-queue id=message-ports:port-message-queue-12>port
    message queue</a> of <var>targetPort</var>:</p>

    <ol><li>
      <p>Let <var>finalTargetPort</var> be the <code id=message-ports:messageport-15><a href=#messageport>MessagePort</a></code> in whose <a href=#port-message-queue id=message-ports:port-message-queue-13>port message
      queue</a> the task now finds itself.</p>

      <p class=note>This can be different from <var>targetPort</var>, if <var>targetPort</var>
      itself was transferred and thus all its tasks moved along with it.</p>
     <li><p>Let <var>messageEventTarget</var> be <var>finalTargetPort</var>'s <a href=#message-event-target id=message-ports:message-event-target>message event
     target</a>.<li><p>Let <var>targetRealm</var> be <var>finalTargetPort</var>'s <a href=webappapis.html#concept-relevant-realm id=message-ports:concept-relevant-realm>relevant realm</a>.<li>
      <p>Let <var>deserializeRecord</var> be
      <a id=message-ports:structureddeserializewithtransfer href=structured-data.html#structureddeserializewithtransfer>StructuredDeserializeWithTransfer</a>(<var>serializeWithTransferResult</var>,
      <var>targetRealm</var>).</p>

      <p>If this throws an exception, catch it, <a href=https://dom.spec.whatwg.org/#concept-event-fire id=message-ports:concept-event-fire-2 data-x-internal=concept-event-fire>fire an
      event</a> named <code id=message-ports:event-messageerror-2><a href=indices.html#event-messageerror>messageerror</a></code> at
      <var>messageEventTarget</var>, using <code id=message-ports:messageevent><a href=comms.html#messageevent>MessageEvent</a></code>, and then return.
     <li><p>Let <var>messageClone</var> be <var>deserializeRecord</var>.[[Deserialized]].<li><p>Let <var>newPorts</var> be a new <a id=message-ports:frozen-array href=https://webidl.spec.whatwg.org/#dfn-frozen-array-type data-x-internal=frozen-array>frozen array</a> consisting of all
     <code id=message-ports:messageport-16><a href=#messageport>MessagePort</a></code> objects in <var>deserializeRecord</var>.[[TransferredValues]], if any,
     maintaining their relative order.<li><p><a href=https://dom.spec.whatwg.org/#concept-event-fire id=message-ports:concept-event-fire-3 data-x-internal=concept-event-fire>Fire an event</a> named <code id=message-ports:event-message-3><a href=indices.html#event-message>message</a></code> at <var>messageEventTarget</var>, using
     <code id=message-ports:messageevent-2><a href=comms.html#messageevent>MessageEvent</a></code>, with the <code id=message-ports:dom-messageevent-data><a href=comms.html#dom-messageevent-data>data</a></code> attribute
     initialized to <var>messageClone</var> and the <code id=message-ports:dom-messageevent-ports><a href=comms.html#dom-messageevent-ports>ports</a></code> attribute initialized to
     <var>newPorts</var>.</ol>
   </ol>

  <p>The <dfn data-dfn-for=MessagePort id=dom-messageport-postmessage-options data-dfn-type=method><code>postMessage(<var>message</var>,
  <var>options</var>)</code></dfn> method steps are:</p>

  <ol><li><p>Let <var>targetPort</var> be the port with which <a id=message-ports:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a> is entangled, if any;
   otherwise let it be null.<li><p>Run the <a href=#message-port-post-message-steps id=message-ports:message-port-post-message-steps>message port post message steps</a> providing <a id=message-ports:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>,
   <var>targetPort</var>, <var>message</var> and <var>options</var>.</ol>

  <p>The <dfn data-dfn-for=MessagePort id=dom-messageport-postmessage data-dfn-type=method><code>postMessage(<var>message</var>,
  <var>transfer</var>)</code></dfn> method steps are:</p>

  <ol><li><p>Let <var>targetPort</var> be the port with which <a id=message-ports:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a> is entangled, if any;
   otherwise let it be null.<li><p>Let <var>options</var> be «[ "<code id=message-ports:dom-structuredserializeoptions-transfer-2><a href=#dom-structuredserializeoptions-transfer>transfer</a></code>" → <var>transfer</var>
   ]».<li><p>Run the <a href=#message-port-post-message-steps id=message-ports:message-port-post-message-steps-2>message port post message steps</a> providing <a id=message-ports:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>,
   <var>targetPort</var>, <var>message</var> and <var>options</var>.</ol>

  <hr>

  <p>The <dfn data-dfn-for=MessagePort id=dom-messageport-start data-dfn-type=method><code>start()</code></dfn>
  method steps are to enable <a id=message-ports:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#port-message-queue id=message-ports:port-message-queue-14>port message queue</a>, if it is not
  already enabled.</p>

  <hr>

  <p>The <dfn data-dfn-for=MessagePort id=dom-messageport-close data-dfn-type=method><code>close()</code></dfn>
  method steps are:</p>

  <ol><li><p>Set <a id=message-ports:this-6 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=message-ports:detached href=structured-data.html#detached>[[Detached]]</a> internal slot value to true.<li><p>If <a id=message-ports:this-7 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a> is entangled, <a href=#disentangle id=message-ports:disentangle>disentangle</a> it.</ol>

  <hr>

  <p>The following are the <a id=message-ports:event-handlers href=webappapis.html#event-handlers>event handlers</a> (and their corresponding <a href=webappapis.html#event-handler-event-type id=message-ports:event-handler-event-type>event handler event types</a>) that must be supported,
  as <a id=message-ports:event-handler-idl-attributes href=webappapis.html#event-handler-idl-attributes>event handler IDL attributes</a>, by all objects implementing the
  <code id=message-ports:messageport-17><a href=#messageport>MessagePort</a></code> interface:</p>

  <table><thead><tr><th><a href=webappapis.html#event-handlers id=message-ports:event-handlers-2>Event handler</a> <th><a id=message-ports:event-handler-event-type-2 href=webappapis.html#event-handler-event-type>Event handler event type</a>
   <tbody><tr><td><dfn data-dfn-for=MessagePort id=handler-messageport-onclose data-dfn-type=attribute><code>onclose</code></dfn> <td> <code id=message-ports:event-close-3><a href=indices.html#event-close>close</a></code>
  </table>

  <p>The first time a <code id=message-ports:messageport-18><a href=#messageport>MessagePort</a></code> object's <code id=message-ports:handler-messageeventtarget-onmessage><a href=#handler-messageeventtarget-onmessage>onmessage</a></code> IDL attribute is set, the port's
  <a href=#port-message-queue id=message-ports:port-message-queue-15>port message queue</a> must be enabled, as if the <code id=message-ports:dom-messageport-start-2><a href=#dom-messageport-start>start()</a></code> method had been called.</p>

  


  <h4 id=ports-and-garbage-collection><span class=secno>9.4.5</span> Ports and garbage collection<a href=#ports-and-garbage-collection class=self-link></a></h4>

  
  <p>When a <code id=ports-and-garbage-collection:messageport><a href=#messageport>MessagePort</a></code> object <var>o</var> is garbage collected, if <var>o</var> is
  entangled, then the user agent must <a href=#disentangle id=ports-and-garbage-collection:disentangle>disentangle</a>
  <var>o</var>.</p>

  <p>When a <code id=ports-and-garbage-collection:messageport-2><a href=#messageport>MessagePort</a></code> object <var>o</var> is entangled and <code id=ports-and-garbage-collection:event-message><a href=indices.html#event-message>message</a></code> or <code id=ports-and-garbage-collection:event-messageerror><a href=indices.html#event-messageerror>messageerror</a></code>
  event listener is registered, user agents must act as if <var>o</var>'s entangled
  <code id=ports-and-garbage-collection:messageport-3><a href=#messageport>MessagePort</a></code> object has a strong reference to <var>o</var>.</p>

  <p>Furthermore, a <code id=ports-and-garbage-collection:messageport-4><a href=#messageport>MessagePort</a></code> object must not be garbage collected while there
  exists an event referenced by a <a href=webappapis.html#concept-task id=ports-and-garbage-collection:concept-task>task</a> in a <a id=ports-and-garbage-collection:task-queue href=webappapis.html#task-queue>task
  queue</a> that is to be dispatched on that <code id=ports-and-garbage-collection:messageport-5><a href=#messageport>MessagePort</a></code> object, or while the
  <code id=ports-and-garbage-collection:messageport-6><a href=#messageport>MessagePort</a></code> object's <a href=#port-message-queue id=ports-and-garbage-collection:port-message-queue>port message queue</a> is enabled and not empty.</p>
  

  

  <div class=note>

   <p>Thus, a message port can be received, given an event listener, and then forgotten, and so long
   as that event listener could receive a message, the channel will be maintained.</p>

   <p>Of course, if this was to occur on both sides of the channel, then both ports could be garbage
   collected, since they would not be reachable from live code, despite having a strong reference to
   each other. However, if a message port has a pending message, it is not garbage collected.</p>

  </div>

  

  <p class=note>Authors are strongly encouraged to explicitly close <code id=ports-and-garbage-collection:messageport-7><a href=#messageport>MessagePort</a></code>
  objects to disentangle them, so that their resources can be recollected. Creating many
  <code id=ports-and-garbage-collection:messageport-8><a href=#messageport>MessagePort</a></code> objects and discarding them without closing them can lead to high
  transient memory usage since garbage collection is not necessarily performed promptly, especially
  for <code id=ports-and-garbage-collection:messageport-9><a href=#messageport>MessagePort</a></code>s where garbage collection can involve cross-process coordination.</p>



  <h3 id=broadcasting-to-other-browsing-contexts><span class=secno>9.5</span> <dfn>Broadcasting to other browsing contexts</dfn><a href=#broadcasting-to-other-browsing-contexts class=self-link></a></h3><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel title="The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames or iframes) of the same origin. Messages are broadcasted via a message event fired at all BroadcastChannel objects listening to the channel, except the object that sent the message.">BroadcastChannel</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>38+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API title="The Broadcast Channel API allows basic communication between browsing contexts (that is, windows, tabs, frames, or iframes) and workers on the same origin.">Broadcast_Channel_API</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>38+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  <p>Pages on a single <a id=broadcasting-to-other-browsing-contexts:concept-origin href=browsers.html#concept-origin>origin</a> opened by the same user in the same user agent but in
  different unrelated <a href=document-sequences.html#browsing-context id=broadcasting-to-other-browsing-contexts:browsing-context>browsing contexts</a> sometimes need to
  send notifications to each other, for example "hey, the user logged in over here, check your
  credentials again".</p>

  <p>For elaborate cases, e.g. to manage locking of shared state, to manage synchronization of
  resources between a server and multiple local clients, to share a <code id=broadcasting-to-other-browsing-contexts:websocket-2><a data-x-internal=websocket-2 href=https://websockets.spec.whatwg.org/#websocket>WebSocket</a></code>
  connection with a remote host, and so forth, <a href=workers.html#sharedworker id=broadcasting-to-other-browsing-contexts:sharedworker>shared workers</a> are
  the most appropriate solution.</p>

  <p>For simple cases, though, where a shared worker would be an unreasonable overhead, authors can
  use the simple channel-based broadcast mechanism described in this section.</p>

  <pre><code class='idl'>[<c- g>Exposed</c->=(<c- n>Window</c->,<c- n>Worker</c->)]
<c- b>interface</c-> <dfn id='broadcastchannel' data-dfn-type='interface'><c- g>BroadcastChannel</c-></dfn> : <a id='broadcasting-to-other-browsing-contexts:eventtarget' href='https://dom.spec.whatwg.org/#interface-eventtarget' data-x-internal='eventtarget'><c- n>EventTarget</c-></a> {
  <a href='#dom-broadcastchannel' id='broadcasting-to-other-browsing-contexts:dom-broadcastchannel'><c- g>constructor</c-></a>(<c- b>DOMString</c-> <c- g>name</c->);

  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>DOMString</c-> <a href='#dom-broadcastchannel-name' id='broadcasting-to-other-browsing-contexts:dom-broadcastchannel-name'><c- g>name</c-></a>;
  <c- b>undefined</c-> <a href='#dom-broadcastchannel-postmessage' id='broadcasting-to-other-browsing-contexts:dom-broadcastchannel-postmessage'><c- g>postMessage</c-></a>(<c- b>any</c-> <c- g>message</c->);
  <c- b>undefined</c-> <a href='#dom-broadcastchannel-close' id='broadcasting-to-other-browsing-contexts:dom-broadcastchannel-close'><c- g>close</c-></a>();
  <c- b>attribute</c-> <a id='broadcasting-to-other-browsing-contexts:eventhandler' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-broadcastchannel-onmessage' id='broadcasting-to-other-browsing-contexts:handler-broadcastchannel-onmessage'><c- g>onmessage</c-></a>;
  <c- b>attribute</c-> <a id='broadcasting-to-other-browsing-contexts:eventhandler-2' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-broadcastchannel-onmessageerror' id='broadcasting-to-other-browsing-contexts:handler-broadcastchannel-onmessageerror'><c- g>onmessageerror</c-></a>;
};</code></pre>

  <dl class=domintro><dt><code><var>broadcastChannel</var> = new <a href=#dom-broadcastchannel id=dom-broadcastchannel-dev>BroadcastChannel</a>(<var>name</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/BroadcastChannel title="The BroadcastChannel() constructor creates a new BroadcastChannel and connects it to the underlying channel.">BroadcastChannel/BroadcastChannel</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>38+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>
    <p>Returns a new <code id=broadcasting-to-other-browsing-contexts:broadcastchannel><a href=#broadcastchannel>BroadcastChannel</a></code> object via which messages for the given channel
    name can be sent and received.</p>
   <dt><code><var>broadcastChannel</var>.<a href=#dom-broadcastchannel-name id=dom-broadcastchannel-name-dev>name</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/name title="The read-only BroadcastChannel.name property returns a string, which uniquely identifies the given channel with its name. This name is passed to the BroadcastChannel() constructor at creation time and is therefore read-only.">BroadcastChannel/name</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>38+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd><p>Returns the channel name (as passed to the constructor).<dt><code><var>broadcastChannel</var>.<a href=#dom-broadcastchannel-postmessage id=dom-broadcastchannel-postmessage-dev>postMessage</a>(<var>message</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/postMessage title="The BroadcastChannel.postMessage() sends a message, which can be of any kind of Object, to each listener in any browsing context with the same origin. The message is transmitted as a 'message' event targeted at each BroadcastChannel bound to the channel.">BroadcastChannel/postMessage</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>38+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>
    <p>Sends the given message to other <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-2><a href=#broadcastchannel>BroadcastChannel</a></code> objects set up for this
    channel. Messages can be structured objects, e.g. nested objects and arrays.</p>
   <dt><code><var>broadcastChannel</var>.<a href=#dom-broadcastchannel-close id=dom-broadcastchannel-close-dev>close</a>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/close title="The BroadcastChannel.close() terminates the connection to the underlying channel, allowing the object to be garbage collected. This is a necessary step to perform as there is no other way for a browser to know that this channel is not needed anymore.">BroadcastChannel/close</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>38+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd><p>Closes the <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-3><a href=#broadcastchannel>BroadcastChannel</a></code> object, opening it up to garbage
   collection.</dl>

  

  <p>A <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-4><a href=#broadcastchannel>BroadcastChannel</a></code> object has a <dfn id=channel-name>channel name</dfn> and a <dfn id=concept-broadcastchannel-closed>closed flag</dfn>.</p>

  <p>The <dfn id=dom-broadcastchannel><code>new BroadcastChannel(<var>name</var>)</code></dfn>
  constructor steps are:</p>

  <ol><li><p>Set <a id=broadcasting-to-other-browsing-contexts:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#channel-name id=broadcasting-to-other-browsing-contexts:channel-name>channel name</a> to <var>name</var>.<li><p>Set <a id=broadcasting-to-other-browsing-contexts:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-broadcastchannel-closed id=broadcasting-to-other-browsing-contexts:concept-broadcastchannel-closed>closed flag</a>
   to false.</ol>

  <p>The <dfn data-dfn-for=BroadcastChannel id=dom-broadcastchannel-name data-dfn-type=attribute><code>name</code></dfn> getter steps are to return
  <a id=broadcasting-to-other-browsing-contexts:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#channel-name id=broadcasting-to-other-browsing-contexts:channel-name-2>channel name</a>.</p>

  <p>A <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-5><a href=#broadcastchannel>BroadcastChannel</a></code> object is said to be <dfn id=eligible-for-messaging>eligible for messaging</dfn> when
  its <a id=broadcasting-to-other-browsing-contexts:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant global object</a> is either:</p>

  <ul><li><p>a <code id=broadcasting-to-other-browsing-contexts:window><a href=nav-history-apis.html#window>Window</a></code> object whose <a href=nav-history-apis.html#concept-document-window id=broadcasting-to-other-browsing-contexts:concept-document-window>associated
   <code>Document</code></a> is <a id=broadcasting-to-other-browsing-contexts:fully-active href=document-sequences.html#fully-active>fully active</a>, or<li><p>a <code id=broadcasting-to-other-browsing-contexts:workerglobalscope><a href=workers.html#workerglobalscope>WorkerGlobalScope</a></code> object whose <a href=workers.html#dom-workerglobalscope-closing id=broadcasting-to-other-browsing-contexts:dom-workerglobalscope-closing>closing</a> flag is false and is not <a href=workers.html#suspendable-worker id=broadcasting-to-other-browsing-contexts:suspendable-worker>suspendable</a>.</ul>

  <p>The <dfn data-dfn-for=BroadcastChannel id=dom-broadcastchannel-postmessage data-dfn-type=method><code>postMessage(<var>message</var>)</code></dfn> method
  steps are:</p>

  <ol><li><p>If <a id=broadcasting-to-other-browsing-contexts:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a> is not <a href=#eligible-for-messaging id=broadcasting-to-other-browsing-contexts:eligible-for-messaging>eligible for messaging</a>, then return.<li><p>If <a id=broadcasting-to-other-browsing-contexts:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-broadcastchannel-closed id=broadcasting-to-other-browsing-contexts:concept-broadcastchannel-closed-2>closed flag</a>
   is true, then throw an <a id=broadcasting-to-other-browsing-contexts:invalidstateerror href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a>
   <code id=broadcasting-to-other-browsing-contexts:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>serialized</var> be <a id=broadcasting-to-other-browsing-contexts:structuredserialize href=structured-data.html#structuredserialize>StructuredSerialize</a>(<var>message</var>). Rethrow
   any exceptions.<li><p>Let <var>sourceOrigin</var> be <a id=broadcasting-to-other-browsing-contexts:this-6 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=broadcasting-to-other-browsing-contexts:relevant-settings-object href=webappapis.html#relevant-settings-object>relevant settings object</a>'s
   <a href=webappapis.html#concept-settings-object-origin id=broadcasting-to-other-browsing-contexts:concept-settings-object-origin>origin</a>.<li><p>Let <var>sourceStorageKey</var> be the result of running <a id=broadcasting-to-other-browsing-contexts:obtain-a-storage-key-for-non-storage-purposes href=https://storage.spec.whatwg.org/#obtain-a-storage-key-for-non-storage-purposes data-x-internal=obtain-a-storage-key-for-non-storage-purposes>obtain a storage key for
   non-storage purposes</a> with <a id=broadcasting-to-other-browsing-contexts:this-7 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=broadcasting-to-other-browsing-contexts:relevant-settings-object-2 href=webappapis.html#relevant-settings-object>relevant settings
   object</a>.<li>
    <p>Let <var>destinations</var> be a list of <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-6><a href=#broadcastchannel>BroadcastChannel</a></code> objects that
    match the following criteria:</p>

    <ul><li><p>They are <a href=#eligible-for-messaging id=broadcasting-to-other-browsing-contexts:eligible-for-messaging-2>eligible for messaging</a>.<li><p>The result of running <a id=broadcasting-to-other-browsing-contexts:obtain-a-storage-key-for-non-storage-purposes-2 href=https://storage.spec.whatwg.org/#obtain-a-storage-key-for-non-storage-purposes data-x-internal=obtain-a-storage-key-for-non-storage-purposes>obtain a storage key for non-storage purposes</a> with
     their <a id=broadcasting-to-other-browsing-contexts:relevant-settings-object-3 href=webappapis.html#relevant-settings-object>relevant settings object</a> <a href=https://storage.spec.whatwg.org/#storage-key-equal id=broadcasting-to-other-browsing-contexts:storage-key-equal data-x-internal=storage-key-equal>equals</a>
     <var>sourceStorageKey</var>.<li><p>Their <a href=#channel-name id=broadcasting-to-other-browsing-contexts:channel-name-3>channel name</a> <a id=broadcasting-to-other-browsing-contexts:is href=https://infra.spec.whatwg.org/#string-is data-x-internal=is>is</a> <a id=broadcasting-to-other-browsing-contexts:this-8 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#channel-name id=broadcasting-to-other-browsing-contexts:channel-name-4>channel
     name</a>.</ul>
   <li><p>Remove <var>source</var> from <var>destinations</var>.<li><p>Sort <var>destinations</var> such that all <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-7><a href=#broadcastchannel>BroadcastChannel</a></code> objects whose
   <a href=webappapis.html#relevant-agent id=broadcasting-to-other-browsing-contexts:relevant-agent>relevant agents</a> are the same are sorted in creation order,
   oldest first. (This does not define a complete ordering. Within this constraint, user agents may
   sort the list in any <a id=broadcasting-to-other-browsing-contexts:implementation-defined href=https://infra.spec.whatwg.org/#implementation-defined data-x-internal=implementation-defined>implementation-defined</a> manner.)<li>
    <p>For each <var>destination</var> in <var>destinations</var>, <a id=broadcasting-to-other-browsing-contexts:queue-a-global-task href=webappapis.html#queue-a-global-task>queue a global task</a>
    on the <a id=broadcasting-to-other-browsing-contexts:dom-manipulation-task-source href=webappapis.html#dom-manipulation-task-source>DOM manipulation task source</a> given <var>destination</var>'s <a id=broadcasting-to-other-browsing-contexts:concept-relevant-global-2 href=webappapis.html#concept-relevant-global>relevant
    global object</a> to perform the following steps:</p>

    <ol><li><p>If <var>destination</var>'s <a href=#concept-broadcastchannel-closed id=broadcasting-to-other-browsing-contexts:concept-broadcastchannel-closed-3>closed
     flag</a> is true, then abort these steps.<li><p>Let <var>targetRealm</var> be <var>destination</var>'s <a href=webappapis.html#concept-relevant-realm id=broadcasting-to-other-browsing-contexts:concept-relevant-realm>relevant realm</a>.<li>
      <p>Let <var>data</var> be <a id=broadcasting-to-other-browsing-contexts:structureddeserialize href=structured-data.html#structureddeserialize>StructuredDeserialize</a>(<var>serialized</var>,
      <var>targetRealm</var>).</p>

      <p>If this throws an exception, catch it, <a href=https://dom.spec.whatwg.org/#concept-event-fire id=broadcasting-to-other-browsing-contexts:concept-event-fire data-x-internal=concept-event-fire>fire an
      event</a> named <code id=broadcasting-to-other-browsing-contexts:event-messageerror><a href=indices.html#event-messageerror>messageerror</a></code> at
      <var>destination</var>, using <code id=broadcasting-to-other-browsing-contexts:messageevent><a href=comms.html#messageevent>MessageEvent</a></code>, with the <code id=broadcasting-to-other-browsing-contexts:dom-messageevent-origin><a href=comms.html#dom-messageevent-origin>origin</a></code> attribute initialized to the <a href=browsers.html#ascii-serialisation-of-an-origin id=broadcasting-to-other-browsing-contexts:ascii-serialisation-of-an-origin>serialization</a> of <var>sourceOrigin</var>, and then
      abort these steps.</p>
     <li><p><a href=https://dom.spec.whatwg.org/#concept-event-fire id=broadcasting-to-other-browsing-contexts:concept-event-fire-2 data-x-internal=concept-event-fire>Fire an event</a> named <code id=broadcasting-to-other-browsing-contexts:event-message><a href=indices.html#event-message>message</a></code> at <var>destination</var>, using
     <code id=broadcasting-to-other-browsing-contexts:messageevent-2><a href=comms.html#messageevent>MessageEvent</a></code>, with the <code id=broadcasting-to-other-browsing-contexts:dom-messageevent-data><a href=comms.html#dom-messageevent-data>data</a></code> attribute
     initialized to <var>data</var> and the <code id=broadcasting-to-other-browsing-contexts:dom-messageevent-origin-2><a href=comms.html#dom-messageevent-origin>origin</a></code>
     attribute initialized to the <a href=browsers.html#ascii-serialisation-of-an-origin id=broadcasting-to-other-browsing-contexts:ascii-serialisation-of-an-origin-2>serialization</a> of
     <var>sourceOrigin</var>.</ol>
   </ol>

  <p>While a <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-8><a href=#broadcastchannel>BroadcastChannel</a></code> object whose <a href=#concept-broadcastchannel-closed id=broadcasting-to-other-browsing-contexts:concept-broadcastchannel-closed-4>closed flag</a> is false has an event listener
  registered for <code id=broadcasting-to-other-browsing-contexts:event-message-2><a href=indices.html#event-message>message</a></code> or <code id=broadcasting-to-other-browsing-contexts:event-messageerror-2><a href=indices.html#event-messageerror>messageerror</a></code> events, there must be a strong reference from the
  <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-9><a href=#broadcastchannel>BroadcastChannel</a></code> object's <a id=broadcasting-to-other-browsing-contexts:concept-relevant-global-3 href=webappapis.html#concept-relevant-global>relevant global object</a> to the
  <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-10><a href=#broadcastchannel>BroadcastChannel</a></code> object itself.</p>

  <p>The <dfn data-dfn-for=BroadcastChannel id=dom-broadcastchannel-close data-dfn-type=method><code>close()</code></dfn> method steps are to set
  <a id=broadcasting-to-other-browsing-contexts:this-9 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-broadcastchannel-closed id=broadcasting-to-other-browsing-contexts:concept-broadcastchannel-closed-5>closed flag</a> to true.</p>

  

  <p class=note>Authors are strongly encouraged to explicitly close <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-11><a href=#broadcastchannel>BroadcastChannel</a></code>
  objects when they are no longer needed, so that they can be garbage collected. Creating many
  <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-12><a href=#broadcastchannel>BroadcastChannel</a></code> objects and discarding them while leaving them with an event
  listener and without closing them can lead to an apparent memory leak, since the objects will
  continue to live for as long as they have an event listener (or until their page or worker is
  closed).</p>

  

  <hr>

  <p>The following are the <a id=broadcasting-to-other-browsing-contexts:event-handlers href=webappapis.html#event-handlers>event handlers</a> (and their corresponding <a href=webappapis.html#event-handler-event-type id=broadcasting-to-other-browsing-contexts:event-handler-event-type>event handler event types</a>) that must be supported,
  as <a id=broadcasting-to-other-browsing-contexts:event-handler-idl-attributes href=webappapis.html#event-handler-idl-attributes>event handler IDL attributes</a>, by all objects implementing the
  <code id=broadcasting-to-other-browsing-contexts:broadcastchannel-13><a href=#broadcastchannel>BroadcastChannel</a></code> interface:</p>

  <table><thead><tr><th><a href=webappapis.html#event-handlers id=broadcasting-to-other-browsing-contexts:event-handlers-2>Event handler</a> <th><a id=broadcasting-to-other-browsing-contexts:event-handler-event-type-2 href=webappapis.html#event-handler-event-type>Event handler event type</a>
   <tbody><tr><td><dfn data-dfn-for=BroadcastChannel id=handler-broadcastchannel-onmessage data-dfn-type=attribute><code>onmessage</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/message_event title="The message event is fired on a BroadcastChannel object when a message arrives on that channel.">BroadcastChannel/message_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>38+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><td> <code id=broadcasting-to-other-browsing-contexts:event-message-3><a href=indices.html#event-message>message</a></code>
    <tr><td><dfn data-dfn-for=BroadcastChannel id=handler-broadcastchannel-onmessageerror data-dfn-type=attribute><code>onmessageerror</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/messageerror_event title="The messageerror event is fired on a BroadcastChannel object when a message that can't be deserialized arrives on the channel.">BroadcastChannel/messageerror_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>57+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>60+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>47+</span></span></div></div></div><td> <code id=broadcasting-to-other-browsing-contexts:event-messageerror-3><a href=indices.html#event-messageerror>messageerror</a></code>
  </table>

  

  <div class=example>

   <p>Suppose a page wants to know when the user logs out, even when the user does so from another
   tab at the same site:</p>

   <pre><code class='js'><c- a>var</c-> authChannel <c- o>=</c-> <c- k>new</c-> BroadcastChannel<c- p>(</c-><c- t>&apos;auth&apos;</c-><c- p>);</c->
authChannel<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data <c- o>==</c-> <c- t>&apos;logout&apos;</c-><c- p>)</c->
    showLogout<c- p>();</c->
<c- p>}</c->

<c- a>function</c-> logoutRequested<c- p>()</c-> <c- p>{</c->
  <c- c1>// called when the user asks us to log them out</c->
  doLogout<c- p>();</c->
  showLogout<c- p>();</c->
  authChannel<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;logout&apos;</c-><c- p>);</c->
<c- p>}</c->

<c- a>function</c-> doLogout<c- p>()</c-> <c- p>{</c->
  <c- c1>// actually log the user out (e.g. clearing cookies)</c->
  <c- c1>// ...</c->
<c- p>}</c->

<c- a>function</c-> showLogout<c- p>()</c-> <c- p>{</c->
  <c- c1>// update the UI to indicate we&apos;re logged out</c->
  <c- c1>// ...</c->
<c- p>}</c-></code></pre>

  </div>



  <nav><a href=server-sent-events.html>← 9.2 Server-sent events</a> — <a href=index.html>Table of Contents</a> — <a href=workers.html>10 Web workers →</a></nav>
